package com.youshang.config;

import com.youshang.annotation.AccessLimit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;


@Deprecated
@Component
public class FangshuaInterceptor implements HandlerInterceptor {
 
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
        //判断请求是否属于方法的请求
        if(handler instanceof HandlerMethod){
            HandlerMethod hm = (HandlerMethod) handler;
            //获取方法中的注解,看是否有该注解
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if(accessLimit == null){
                return true;
            }
            int seconds = accessLimit.seconds();
            int retryCount = accessLimit.retryCount();
            boolean login = accessLimit.needLogin();
            String requestURI = request.getServletPath();
            if (seconds <= 0) {throw new RuntimeException("加载时间不允许小于0");}

            //获取请求参数的hashCode
            int requestHashCode = 0;
            String method = request.getMethod();
            if (RequestMethod.GET.name().equals(method)){
                requestHashCode = (StringUtils.isEmpty(request.getQueryString()) ? "" : request.getQueryString()).hashCode() ;
            }else{
                requestHashCode = getBodyString(request).hashCode();
            }

            String userId = "";
            if(login){
                //获取用户ID
                userId = "123456";
            }

            //key = 请求路径 + 操作用户ID + 请求参数的转String的hashCode值
            String key = requestURI+userId+requestHashCode;
            Object obj = redisTemplate.opsForValue().get(key);
            System.out.println("获取到的：key:"+obj + " " + key);
            if (null == obj) {
                //当用户第一次访问时，存储当前用户信息+请求路径
                redisTemplate.opsForValue().set(key,0,seconds, TimeUnit.SECONDS);
            }else {
                int accessCount = (int) obj;
                if (retryCount > accessCount) {
                    System.out.println("进行递增。。。。");
                    redisTemplate.opsForValue().increment(key,1);
                }else {
                    Long expire = redisTemplate.opsForValue().getOperations().getExpire(key);
                    System.out.println("过期时间为："+expire);
                    //返回前端
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 获取请求Body
     *
     * @param request
     *
     * @return
     */
    public static String getBodyString(final ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

    /**
     * Description: 复制输入流</br>
     *
     * @param inputStream
     *
     * @return</br>
     */
    public static InputStream cloneInputStream(ServletInputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }

}
